home *** CD-ROM | disk | FTP | other *** search
- /* WaveTableStorage.c */
- /*****************************************************************************/
- /* */
- /* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
- /* Copyright (C) 1994 Thomas R. Lawrence */
- /* */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to the Free Software */
- /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* */
- /* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
- /* */
- /*****************************************************************************/
-
- #include "MiscInfo.h"
- #include "Audit.h"
- #include "Debug.h"
- #include "Definitions.h"
-
- #include "WaveTableStorage.h"
- #include "Array.h"
- #include "Memory.h"
- #include "DataMunging.h"
-
-
- struct WaveTableStorageRec
- {
- ArrayRec* ListOfTables; /* of char*s or short*s */
- NumBitsType NumBits;
- long NumFrames;
- };
-
-
- /* create a new wave table storage object */
- WaveTableStorageRec* NewWaveTableStorage(NumBitsType NumBits, long NumFrames)
- {
- WaveTableStorageRec* Storage;
-
- ERROR((NumBits != eSample8bit) && (NumBits != eSample16bit),
- PRERR(ForceAbort,"NewWaveTableStorage: bad number of bits"));
- ERROR((NumFrames != 2) && (NumFrames != 4) && (NumFrames != 8) && (NumFrames != 16)
- && (NumFrames != 32) && (NumFrames != 64) && (NumFrames != 128)
- && (NumFrames != 256) && (NumFrames != 512) && (NumFrames != 1024)
- && (NumFrames != 2048) && (NumFrames != 4096) && (NumFrames != 8192)
- && (NumFrames != 16384) && (NumFrames != 32768) && (NumFrames != 65536),
- PRERR(ForceAbort,"NewWaveTableStorage: bad number of frames"));
- Storage = (WaveTableStorageRec*)AllocPtrCanFail(sizeof(WaveTableStorageRec),
- "WaveTableStorageRec");
- if (Storage == NIL)
- {
- FailurePoint1:
- return NIL;
- }
- Storage->ListOfTables = NewArray();
- if (Storage->ListOfTables == NIL)
- {
- ReleasePtr((char*)Storage);
- goto FailurePoint1;
- }
- Storage->NumBits = NumBits;
- Storage->NumFrames = NumFrames;
- return Storage;
- }
-
-
- /* dispose of the wave table storage object */
- void DisposeWaveTableStorage(WaveTableStorageRec* Storage)
- {
- long Scan;
- long Limit;
-
- CheckPtrExistence(Storage);
- Limit = ArrayGetLength(Storage->ListOfTables);
- for (Scan = 0; Scan < Limit; Scan += 1)
- {
- ReleasePtr((char*)ArrayGetElement(Storage->ListOfTables,Scan));
- }
- DisposeArray(Storage->ListOfTables);
- ReleasePtr((char*)Storage);
- }
-
-
- /* get the number of frames per table */
- long WaveTableStorageNumFramesPerTable(WaveTableStorageRec* Storage)
- {
- CheckPtrExistence(Storage);
- return Storage->NumFrames;
- }
-
-
- /* get the number of tables */
- long WaveTableStorageNumTables(WaveTableStorageRec* Storage)
- {
- CheckPtrExistence(Storage);
- return ArrayGetLength(Storage->ListOfTables);
- }
-
-
- /* get the number of bits for the wave table */
- NumBitsType WaveTableStorageNumBits(WaveTableStorageRec* Storage)
- {
- CheckPtrExistence(Storage);
- return Storage->NumBits;
- }
-
-
- /* get a reference to a table. this is NOT copied, and there is no type information. */
- /* it is formatted as an array of characters for 8 bit data or array of shorts for */
- /* 16 bit data. it contains (WaveTableStorageNumFramesPerTable + 1) elements for */
- /* each table. The last element is a repeat of the first, and is provided for */
- /* making anti-aliasing more efficient. */
- void* WaveTableStorageGetTable(WaveTableStorageRec* Storage,
- long Index)
- {
- CheckPtrExistence(Storage);
- ERROR((Index < 0) || (Index >= ArrayGetLength(Storage->ListOfTables)),
- PRERR(ForceAbort,"WaveTableStorageGetTable: index out of range"));
- return ArrayGetElement(Storage->ListOfTables,Index);
- }
-
-
- /* append a new (zeroed out) table to the end of the array */
- MyBoolean WaveTableStorageAppendEntry(WaveTableStorageRec* Storage)
- {
- char* Buffer;
- long Limit;
- long Scan;
-
- CheckPtrExistence(Storage);
- switch (Storage->NumBits)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "WaveTableStorageAppendEntry: internal invalid num bits"));
- break;
- case eSample8bit:
- Buffer = AllocPtrCanFail(Storage->NumFrames + 1,
- "WaveTableStorageAppendEntry");
- break;
- case eSample16bit:
- Buffer = AllocPtrCanFail(sizeof(short) * (Storage->NumFrames + 1),
- "WaveTableStorageAppendEntry");
- break;
- }
- if (Buffer == NIL)
- {
- FailurePoint1:
- return False;
- }
- if (!ArrayAppendElement(Storage->ListOfTables,Buffer))
- {
- FailurePoint2:
- ReleasePtr(Buffer);
- goto FailurePoint1;
- }
- Limit = PtrSize(Buffer);
- for (Scan = 0; Scan < Limit; Scan += 1)
- {
- Buffer[Scan] = 0;
- }
- return True;
- }
-
-
- /* put a value into a frame in a table */
- void WaveTableStorageSetFrame(WaveTableStorageRec* Storage,
- long TableIndex, long FrameIndex, largefixedsigned Value)
- {
- long NormalizedValue;
- char* Reference;
-
- CheckPtrExistence(Storage);
- ERROR((TableIndex < 0) || (TableIndex >= ArrayGetLength(Storage->ListOfTables)),
- PRERR(ForceAbort,"WaveTableStorageSetFrame: table index out of range"));
- Reference = (char*)ArrayGetElement(Storage->ListOfTables,TableIndex);
- ERROR((FrameIndex < 0) || (FrameIndex >= Storage->NumFrames),
- PRERR(ForceAbort,"WaveTableStorageSetFrame: frame index out of range"));
- switch (Storage->NumBits)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "WaveTableStorageSetFrame: internal invalid num bits"));
- break;
- case eSample8bit:
- NormalizedValue = roundtonearest(largefixed2double(Value) * MAX8BIT);
- if (NormalizedValue < MIN8BIT)
- {
- NormalizedValue = MIN8BIT;
- }
- else if (NormalizedValue > MAX8BIT)
- {
- NormalizedValue = MAX8BIT;
- }
- PRNGCHK(Reference,&(((char*)Reference)[FrameIndex]),sizeof(char));
- ((char*)Reference)[FrameIndex] = NormalizedValue;
- if (FrameIndex == 0)
- {
- PRNGCHK(Reference,&(((char*)Reference)[Storage->NumFrames]),
- sizeof(char));
- ((char*)Reference)[Storage->NumFrames] = NormalizedValue;
- }
- break;
- case eSample16bit:
- NormalizedValue = roundtonearest(largefixed2double(Value) * MAX16BIT);
- if (NormalizedValue < MIN16BIT)
- {
- NormalizedValue = MIN16BIT;
- }
- else if (NormalizedValue > MAX16BIT)
- {
- NormalizedValue = MAX16BIT;
- }
- PRNGCHK(Reference,&(((short*)Reference)[FrameIndex]),sizeof(short));
- ((short*)Reference)[FrameIndex] = NormalizedValue;
- if (FrameIndex == 0)
- {
- PRNGCHK(Reference,&(((short*)Reference)[Storage->NumFrames]),
- sizeof(short));
- ((short*)Reference)[Storage->NumFrames] = NormalizedValue;
- }
- break;
- }
- }
-
-
- /* get a value from a frame in a table */
- largefixedsigned WaveTableStorageGetFrame(WaveTableStorageRec* Storage,
- long TableIndex, long FrameIndex)
- {
- double ReturnValue;
- char* Reference;
-
- CheckPtrExistence(Storage);
- ERROR((TableIndex < 0) || (TableIndex >= ArrayGetLength(Storage->ListOfTables)),
- PRERR(ForceAbort,"WaveTableStorageGetFrame: table index out of range"));
- Reference = (char*)ArrayGetElement(Storage->ListOfTables,TableIndex);
- ERROR((FrameIndex < 0) || (FrameIndex >= Storage->NumFrames),
- PRERR(ForceAbort,"WaveTableStorageGetFrame: frame index out of range"));
- switch (Storage->NumBits)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "WaveTableStorageGetFrame: internal invalid num bits"));
- break;
- case eSample8bit:
- PRNGCHK(Reference,&(((char*)Reference)[FrameIndex]),sizeof(char));
- ReturnValue = ((double)((signed char*)Reference)[FrameIndex]) / MAX8BIT;
- break;
- case eSample16bit:
- PRNGCHK(Reference,&(((short*)Reference)[FrameIndex]),sizeof(short));
- ReturnValue = ((double)((signed short*)Reference)[FrameIndex]) / MAX16BIT;
- break;
- }
- return double2largefixed(ReturnValue);
- }
-
-
- /* make a duplicate of the wave table */
- WaveTableStorageRec* WaveTableDuplicate(WaveTableStorageRec* Original)
- {
- WaveTableStorageRec* Copy;
- long Limit;
- long Scan;
-
- CheckPtrExistence(Original);
-
- Copy = (WaveTableStorageRec*)AllocPtrCanFail(sizeof(WaveTableStorageRec),
- "WaveTableStorageRec");
- if (Copy == NIL)
- {
- FailurePoint1:
- return NIL;
- }
- Copy->NumBits = Original->NumBits;
- Copy->NumFrames = Original->NumFrames;
-
- Copy->ListOfTables = NewArray();
- if (Copy->ListOfTables == NIL)
- {
- FailurePoint2:
- ReleasePtr((char*)Copy);
- goto FailurePoint1;
- }
-
- Limit = ArrayGetLength(Original->ListOfTables);
- for (Scan = 0; Scan < Limit; Scan += 1)
- {
- char* SliceCopy;
-
- SliceCopy = CopyPtr((char*)ArrayGetElement(Original->ListOfTables,Scan));
- if (SliceCopy == NIL)
- {
- /* bummer */
- FailurePoint3:
- Limit = ArrayGetLength(Copy->ListOfTables);
- for (Scan = 0; Scan < Limit; Scan += 1)
- {
- ReleasePtr((char*)ArrayGetElement(Copy->ListOfTables,Scan));
- }
- DisposeArray(Copy->ListOfTables);
- goto FailurePoint2;
- }
- SetTag(SliceCopy,"WaveTableStorageAppendEntry");
- if (!ArrayAppendElement(Copy->ListOfTables,SliceCopy))
- {
- FailurePoint3a:
- ReleasePtr((char*)SliceCopy);
- goto FailurePoint3;
- }
- }
-
- return Copy;
- }
-